package com.faithlibraryplus;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import resources.Item;
import resources.Macro;
import resources.Member;
import resources.Query;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
//import android.content.ClipData;
//import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
//import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.ViewFlipper;

public class MainActivity extends Activity {
	List<Item> _items = null;
	List<Member> _members = null;
	ViewFlipper viewFlipper;
    float lastX;
    final String _RECIPIENT = "fangcheng.jia@gmail.com";
    final String _SUBJECT = "CCMC Library Queries";
    final String _DB_FILE = "ccmcdb";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		if (savedInstanceState == null) {
			getFragmentManager().beginTransaction()
				.add(R.id.container, new PlaceholderFragment()).commit();
		}
	}
	
	@SuppressWarnings("deprecation")
	private void alert(String msg){
		AlertDialog alertDialog = new AlertDialog.Builder(this).create();
		alertDialog.setTitle("Alert Dialog");
		alertDialog.setMessage(msg);
		alertDialog.setIcon(R.drawable.ic_launcher);
		alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
		        public void onClick(DialogInterface dialog, int which) {}});
		alertDialog.show();
	}
	
	private void exportQuery(String filename, String query, int context){
		FileOutputStream outputStream;
		try {
		  outputStream = openFileOutput(filename, context);
		  outputStream.write(query.getBytes());
		  outputStream.close();
		} catch (Exception e) {
		  e.printStackTrace();
		}
    }
	
	private List<String> importAsset(String fileName){
		AssetManager assetManager = getAssets();
		List<String> info = new ArrayList<String>();
		try {
			InputStream input = assetManager.open(fileName);
			InputStreamReader inputreader = new InputStreamReader(input); 
            BufferedReader buffreader = new BufferedReader(inputreader);
            String line = "";
            while ((line = buffreader.readLine()) != null){
            	info.add(line);
            }
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		return info;
	}
	
	private List<String> importQuery(String query_file){		
		List<String> queries = new ArrayList<String>();
	    try {
	    	InputStream inputStream = openFileInput(query_file);
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String receiveString = "";
            while ( (receiveString = bufferedReader.readLine()) != null ) {
            	queries.add(receiveString);
            }
	    }
	    catch (IOException e) {
	    	e.printStackTrace();
	    }
	    return queries;
	}
	
	private String loadAllQueries(){
    	String result = "";
    	for (String str : importQuery(_DB_FILE)){
    		result += str;
    	}
    	return result;
	}
	
	private void refresh(){
		Spinner spinner = (Spinner) findViewById(R.id.loanFilter);
		List<Item> _item_update = new ArrayList<Item>();
    	if (spinner.getSelectedItem().toString().equals(Macro.LOAN_FILTER_LOAN)){
    		_item_update = Helper.findItemsByStatus(_items, Macro.ITEM_STATUS_ON_SHELF);
    	}
    	else{
    		_item_update = Helper.findItemsByStatus(_items, Macro.ITEM_STATUS_ON_LOAN);
    	}
		String[] array_spinner =
				Helper.reformatItems(_item_update).toArray(new String[_item_update.size()]);
		final Spinner item_spinner = (Spinner) findViewById(R.id.items);
		ArrayAdapter<Object> adapter = new ArrayAdapter<Object>(this,
				android.R.layout.simple_spinner_item, array_spinner);
		item_spinner.setAdapter(adapter);
	}
	
	public void initLoanFilter(){
		String[] array_spinner = {Macro.LOAN_FILTER_LOAN, Macro.LOAN_FILTER_RETURN};
		final Spinner spinner = (Spinner) findViewById(R.id.loanFilter);
		ArrayAdapter<Object> adapter = new ArrayAdapter<Object>(this,
				android.R.layout.simple_spinner_item, array_spinner);
		spinner.setAdapter(adapter);
		spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            	refresh();
            }

            public void onNothingSelected(AdapterView<?> arg0) {}
		});
	}
	
	public void initStatus(){
		String[] array_spinner = {Macro.ITEM_STATUS_ON_SHELF, Macro.ITEM_STATUS_ON_LOAN,
				Macro.ITEM_STATUS_DAMAGED, Macro.ITEM_STATUS_LOST};
		Spinner spinner = (Spinner) findViewById(R.id.status);
		ArrayAdapter<Object> adapter = new ArrayAdapter<Object>(this,
				android.R.layout.simple_spinner_item, array_spinner);
		spinner.setAdapter(adapter);
	}
	
	public void initMembers(){
		List<String> list = importAsset(Macro.DB_MEMBERSHIP + ".csv");
		_members = Helper.memberBuilder(list);
		String[] array_spinner =
				Helper.reformatMembers(_members).toArray(new String[_members.size()+1]);
		Spinner spinner = (Spinner) findViewById(R.id.owner);
		ArrayAdapter<Object> adapter = new ArrayAdapter<Object>(this,
				android.R.layout.simple_spinner_item, array_spinner);
		spinner.setAdapter(adapter);
	}
	
	public void initItems(){
		List<String> list = importAsset(Macro.DB_ITEM + ".csv");
		_items = Helper.itemBuilder(list);
		for (String q: loadAllQueries().split(";")){
			if (q != ""){
				String [] item_info = Query.parse(Macro.DB_ITEM, q);
				Item item_to_update = Helper.findItemById(_items, item_info[3]);
				item_to_update.setStatus(item_info[0]);
				item_to_update.setOwner(item_info[1]);
				item_to_update.setReturnDate(item_info[2]);
			}
		}
		String[] array_spinner =
				Helper.reformatItems(_items).toArray(new String[_items.size()]);
		final Spinner spinner = (Spinner) findViewById(R.id.items);
		ArrayAdapter<Object> adapter = new ArrayAdapter<Object>(this,
				android.R.layout.simple_spinner_item, array_spinner);
		spinner.setAdapter(adapter);
		spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> arg0, View arg1,
            		int arg2, long arg3) {
                Spinner spinner = (Spinner) findViewById(R.id.items);
                Spinner status = (Spinner) findViewById(R.id.status);
                Spinner owner = (Spinner) findViewById(R.id.owner);
		    	Item item = Helper.getItemById(_items,
		    			spinner.getSelectedItem().toString().split(",")[1]);
		    	TextView view = (TextView) findViewById(R.id.item_call_number_v);
		    	view.setText(item.getCallNumber());
		    	view = (TextView) findViewById(R.id.item_type_v);
		    	view.setText(item.getType());
		    	view = (TextView) findViewById(R.id.item_author_v);
		    	view.setText(item.getAuthor());
		    	view = (TextView) findViewById(R.id.item_publish_year_v);
		    	view.setText(item.getPublishYear());
		    	view = (TextView) findViewById(R.id.item_publisher_v);
		    	view.setText(item.getPublisher());
		    	view = (TextView) findViewById(R.id.item_category_v);
		    	view.setText(item.getCategory());
		    	view = (TextView) findViewById(R.id.item_isbn_v);
		    	view.setText(item.getISBN());
		    	view = (TextView) findViewById(R.id.item_reg_date_v);
		    	view.setText(item.getRegisterDate());
		    	view = (TextView) findViewById(R.id.item_price_v);
		    	view.setText(item.getPrice());
		    	if(item.getStatus().equals(Macro.ITEM_STATUS_ON_SHELF)){
		    		status.setSelection(0);
		    	}
		    	else if(item.getStatus().equals(Macro.ITEM_STATUS_ON_LOAN)){
		    		status.setSelection(1);
		    	}
		    	else if(item.getStatus().equals(Macro.ITEM_STATUS_DAMAGED)){
		    		status.setSelection(2);
		    	}
		    	else if(item.getStatus().equals(Macro.ITEM_STATUS_LOST)){
		    		status.setSelection(3);
		    	}
		    	owner.setSelection(Helper.findMemberIndexByName(_members, item.getOwner()));
		    	view = (TextView) findViewById(R.id.item_return_date_v);
		    	view.setText(item.getReturnDate());
            }

            public void onNothingSelected(AdapterView<?> arg0) {}
        });
	}
	
	public void initExitButton(){
		final Activity ref = this;
		Button button= (Button) findViewById(R.id.exit_button);
		button.setOnClickListener(new View.OnClickListener() {
		    @Override
		    public void onClick(View v) {
		    	new AlertDialog.Builder(ref)
				.setTitle("Confirmation")
				.setMessage("Exit?")
				.setIcon(android.R.drawable.ic_dialog_alert)
				.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
						android.os.Process.killProcess(android.os.Process.myPid());
		                System.exit(1);
				    }}).setNegativeButton(android.R.string.no, null).show();
		    }
		});
	}
	
	public void initOKButton(){
		Button button= (Button) findViewById(R.id.ok_button);
		button.setOnClickListener(new View.OnClickListener() {
		    @Override
		    public void onClick(View v) {
		    	Spinner status = (Spinner) findViewById(R.id.status);
		    	Spinner owner = (Spinner) findViewById(R.id.owner);
		    	Spinner item = (Spinner) findViewById(R.id.items);
		    	TextView type = (TextView) findViewById(R.id.item_type_v);
		    	TextView return_date = (TextView) findViewById(R.id.item_return_date_v);
		    	int borrow_days = type.getText().equals(Macro.ITEM_TYPE_BOOK) ? 
		    			Macro.MAX_BOOK_BORROW_DAYS : Macro.MAX_DISK_BORROW_DAYS;
		    	
		    	if (!status.getSelectedItem().toString().equals(Macro.ITEM_STATUS_ON_SHELF)){
		    		if (owner.getSelectedItem().toString().equals(Macro.ITEM_OWNER_NONE)){
		    			alert("Please select an owner");
		    		}
		    		else{
		    			String member_id = owner.getSelectedItem().toString().split(",")[1];
		    			Member member = Helper.getMeberById(_members, member_id);
		    			Date expire = null;
						try {
							expire = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse(
									member.getExpiryDate());
						} catch (ParseException e) {
							e.printStackTrace();
						}
				    	if (new Date().after(expire)){
				    		alert(String.format("Membership expired on %s", expire));
				    	}
				    	else{
				    		String item_id = item.getSelectedItem().toString().split(",")[1];
			    			return_date.setText(Helper.getFutureDateFromToday(borrow_days));
			    			update(Macro.ITEM_STATUS_ON_LOAN,
			    					member.getName(),
				    				return_date.getText().toString(),
				    				item_id);
				    		alert(String.format("%s updated %s",
				        			item.getSelectedItem().toString().split(",")[0],
				        			return_date.getText().toString()));
				    		refresh();
				    	}
		    		}
		    	}
		    	else{
		    		String item_id = item.getSelectedItem().toString().split(",")[1];
		    		owner.setSelection(0);
		    		return_date.setText("");
		    		update(Macro.ITEM_STATUS_ON_SHELF, Macro.ITEM_OWNER_NONE, "", item_id);
		    		alert(String.format("%s on shelf",
		        			item.getSelectedItem().toString().split(",")[0]));
		    		refresh();
		    	}
		    }
		});
	}
	
	public void update(String status, String owner, String return_date, String item_id){
		String set = String.format("%s='%s',%s='%s',%s='%s'",
    			Macro.ITEM_STATUS_L, Codecs.encode(status),
    			Macro.ITEM_OWNER_L, Codecs.encode(owner),
    			Macro.ITEM_RETURN_DATE_L, Codecs.encode(return_date));
    	String condition = String.format("%s='%s'", Macro.ITEM_ID_L,
    			Codecs.encode(item_id));
    	String sql = Query.update(Macro.DB_ITEM, set, condition);
    	String query = String.format("%s;", sql);
		Item item_to_update = Helper.getItemById(_items, item_id);
		item_to_update.setStatus(status);
		item_to_update.setOwner(owner);
		item_to_update.setReturnDate(return_date);
    	exportQuery(_DB_FILE, query, Context.MODE_APPEND);
	}
	
//	public void initCopyButton(){
//		Button button= (Button) findViewById(R.id.copy_button);
//		button.setOnClickListener(new View.OnClickListener() {
//		    @Override
//		    public void onClick(View v) {
//		    	ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); 
//		    	ClipData clip = ClipData.newPlainText("query", loadAllQueries());
//		    	clipboard.setPrimaryClip(clip);
//		    	alert("Queries copied");
//		    }
//		});
//	}
	
	public void initSendButton(){
		Button button= (Button) findViewById(R.id.send_button);
		button.setOnClickListener(new View.OnClickListener() {
		    @Override
		    public void onClick(View v) {
		    	Intent i = new Intent(Intent.ACTION_SEND);
		    	i.setType("message/rfc822");
		    	i.putExtra(Intent.EXTRA_EMAIL  , new String[]{_RECIPIENT});
		    	i.putExtra(Intent.EXTRA_SUBJECT, _SUBJECT);
		    	i.putExtra(Intent.EXTRA_TEXT   , loadAllQueries());
		    	try {
		    	    startActivity(Intent.createChooser(i, "Send mail..."));
		    	} catch (android.content.ActivityNotFoundException e) {
		    		e.printStackTrace();
		    	}
		    }
		});
	}
	
	public void initSearch(){
		final Spinner spinner = (Spinner) findViewById(R.id.search_type);
		final Spinner items = (Spinner) findViewById(R.id.items);
		final EditText search = (EditText) findViewById(R.id.search_field);
		final Activity ref = this;
	    search.addTextChangedListener(new TextWatcher(){
	        public void afterTextChanged(Editable s) {}
	        public void beforeTextChanged(CharSequence s, int start, int count, int after){}
	        public void onTextChanged(CharSequence s, int start, int before, int count){
	        	List<Item> searched_items = new ArrayList<Item>();
            	if (spinner.getSelectedItem().toString().equals(Macro.SEARCH_BY_CALL_NUMBER)){
            		searched_items = Helper.findItemsByCallNumber(_items, search.getText().toString());
            	}
            	else{
            		searched_items = Helper.findItemsByISBN(_items, search.getText().toString());
            	}
            	String[] array_spinner =
            			Helper.reformatItems(searched_items).toArray(new String[searched_items.size()]);
        		ArrayAdapter<Object> adapter = new ArrayAdapter<Object>(ref,
        				android.R.layout.simple_spinner_item, array_spinner);
        		items.setAdapter(adapter);
	        }
	    }); 
	}
	
//	public void initLoadButton(){
//		Button button= (Button) findViewById(R.id.load_button);
//		button.setOnClickListener(new View.OnClickListener() {
//		    @Override
//		    public void onClick(View v) {
//		    	EditText viewer = (EditText) findViewById(R.id.query_field);
//		    	viewer.setText(loadAllQueries());
//		    }
//		});
//	}
	
	public void initClearButton(){
		final Activity ref = this;
		Button button= (Button) findViewById(R.id.clear_button);
		button.setOnClickListener(new View.OnClickListener() {
		    @Override
		    public void onClick(View v) {
		    	new AlertDialog.Builder(ref)
				.setTitle("Confirmation")
				.setMessage("Clear all queries?")
				.setIcon(android.R.drawable.ic_dialog_alert)
				.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
						exportQuery(_DB_FILE, "", Context.MODE_PRIVATE);
//				    	EditText viewer = (EditText) findViewById(R.id.query_field);
//				    	viewer.setText(loadAllQueries());
				    }}).setNegativeButton(android.R.string.no, null).show();
		    }
		});
	}
	
//	public boolean onTouchEvent(MotionEvent touchevent) {
//		viewFlipper = (ViewFlipper) findViewById(R.id.view_flipper);
//		switch (touchevent.getAction()){
//			case MotionEvent.ACTION_DOWN:{
//                lastX = touchevent.getX();
//                break;
//            }
//            case MotionEvent.ACTION_UP:{
//            	float currentX = touchevent.getX();
//                if (lastX < currentX) {
//                    if (viewFlipper.getDisplayedChild() == 0)
//                        break;
//                    viewFlipper.setInAnimation(this, R.anim.in_from_left);
//                    viewFlipper.setOutAnimation(this, R.anim.out_to_right);
//                    viewFlipper.showNext();
//                } 
//                if (lastX > currentX){
//                    if (viewFlipper.getDisplayedChild() == 1)
//                        break;
//                    viewFlipper.setInAnimation(this, R.anim.in_from_right);
//                    viewFlipper.setOutAnimation(this, R.anim.out_to_left);
//                    viewFlipper.showPrevious();
//                    }
//                break;
//            }
//        }
//		return false;
//    }
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		initItems();
		initMembers();
		initStatus();
		initExitButton();
		initLoanFilter();
		initOKButton();
		initSendButton();
//		initLoadButton();
		initClearButton();
//		initCopyButton();
		initSearch();
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	/**
	 * A placeholder fragment containing a simple view.
	 */
	public static class PlaceholderFragment extends Fragment {

		public PlaceholderFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			View rootView = inflater.inflate(R.layout.fragment_main, container,
					false);
			return rootView;
		}
	}
}
